from mapper import ClassModel, TableModel, FieldToColumnMap, FieldModel, Map
from nameMangler import PythonNameMangler
import columns

__author__ = 'romilly'

class ClassModelBuilder:
    def __init__(self, modelledClass):
        self._modelledClass = modelledClass
        self._fieldModels = []

    def withField(self, arg):
        if isinstance(arg, FieldModel):
            self.addFieldModel(arg)
        else:
            self.addFieldModel(FieldModel(arg))
        return self

    def build(self):
        return ClassModel(self._modelledClass, self._fieldModels)

    def addFieldModel(self, fieldModel):
        self._fieldModels.append(fieldModel)
        return self

class AbstractBuilderForSomethingWithColumns(object):
    def __init__(self):
        self._columnModels = []

    def withColumn(self, column, size=None):
        self.withStringColumn(column, size)
        return self

    def withStringColumn(self, column, size=None):
        self.addColumnModel(columns.StringColumnModel(column, size))
        return self

    def withDateColumn(self, column):
        self.addColumnModel(columns.DateColumnModel(column))
        return self

    def withDecimalColumn(self, column, size, precision):
        self.addColumnModel(columns.DecimalColumnModel(column, size, precision))
        return self

    def withIntegerColumn(self, column, size):
        self.addColumnModel(columns.IntegerColumnModel(column, size))
        return self

    def addColumnModel(self, columnModel):
        self._columnModels.append(columnModel)

class TableModelBuilder(AbstractBuilderForSomethingWithColumns):
    def __init__(self, tableName):
        super(TableModelBuilder, self).__init__()
        self._tableName = tableName

    def build(self):
        return TableModel(self._tableName, self._columnModels)

class MapBuilder(AbstractBuilderForSomethingWithColumns):
    def __init__(self, mappedClass, nameMangler=PythonNameMangler()):
        super(MapBuilder, self).__init__()
        self._mappedClass = mappedClass
        self._nameMangler = nameMangler

    def makeFieldName(self, columnModel):
        return self._nameMangler.makeFieldName(columnModel.name())

    def buildClassModel(self):
        self._fieldModels = list([FieldModel(self.makeFieldName(columnModel)) for columnModel in self._columnModels])
        return ClassModel(self._mappedClass, self._fieldModels)

    def build(self):
        return Map(self.buildClassModel(), self.buildTableModel(), self.buildFieldToColumnMaps())

    def makeTableName(self):
        return self._nameMangler.makeTableName(self._mappedClass.__name__)

    def buildTableModel(self):
        return TableModel(self.makeTableName(), self._columnModels)

    def buildFieldToColumnMaps(self):
        return list([FieldToColumnMap(fieldModel.name(), columnModel.name()) for (fieldModel, columnModel)
                     in zip(self._fieldModels, self._columnModels)])




  